package spitfire.ksim.algorithm;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import spitfire.ksim.data.KNodeSnapshot;
import spitfire.ksim.data.KSensorSnapshot;

public class AccumulativeSelection implements RequestAlgorithm {
	
	@Override
	public String requestForSD(FuzzyRuleBase ruleBase, KNodeSnapshot snapshot) {
		System.out.println("Requesting with Accumulative");
		// Map for recording the score sum for each SD
		Map<String, Double> sdScoreSumMap = new HashMap<String, Double>();

		Map<String, KSensorSnapshot> typeSnrSnapShotMap = snapshot.getSensorSnapshotMap();
		// For each sensor type
		for (Entry<String, KSensorSnapshot> entry : typeSnrSnapShotMap.entrySet()) {
			String sensorType = entry.getKey();
//			List<Long> timeStampList = entry.getValue().getTimeStampList();
			List<Double> dataList = entry.getValue().getDataList();
			if ( ! ruleBase.containsSensorType(sensorType)) {
				// no such type category
				continue;
			}
			List<FuzzyEntry> feList = ruleBase.getFuzzyEntryListOf(sensorType);
			
			// Check data adequacy
//			if (!PreprocAndValidationAlgorithm.procAndValid(timeStampList, dataList)) {
//				System.out.println("Not enough data for requesting");
//				continue;
//			}
			
			System.out.println("Calculate score for <" + sensorType + ">");
			Map<String, Double> sdScoreMap = new HashMap<String, Double>();
			for (FuzzyEntry fe : feList) {
				double sc = SimilarityAlgorithm.calculateScore(dataList, fe.getRule());
				String sd = fe.getSd();
				if (!sdScoreMap.containsKey(sd) || sdScoreMap.get(sd) < sc) {
					sdScoreMap.put(sd, sc);
				}
			}
			for (Entry<String, Double> sdScoreEntry : sdScoreMap.entrySet()) {
				String sd = sdScoreEntry.getKey();
				Double sc = sdScoreEntry.getValue();
				System.out.println("Similarity to <"+sd+">: " + sc);
				if (sdScoreSumMap.containsKey(sd)) {
					Double scoreSum = sdScoreSumMap.get(sd);
					sdScoreSumMap.put(sd, (scoreSum + sc));
				} else {
					sdScoreSumMap.put(sd, sc);
				}
			}
		}
		
		String maxSD = null;
		double maxSc = 0;
		for (Entry<String, Double> sdScoreSumEntry : sdScoreSumMap.entrySet()) {
			String sd = sdScoreSumEntry.getKey();
			double score = sdScoreSumEntry.getValue();
			if (score > maxSc) {
				maxSc = score;
				maxSD = sd;
			}
		}
		
		if (maxSD == null) {
			System.out.println("No SD selected");
		} else {
			System.out.println("<" + maxSD + "> selected with total score: " + maxSc);
		}
		return maxSD;
	}

}
